package com.cksys.achievement.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cksys.achievement.entity.User;
import com.cksys.achievement.enums.EmailStatusEnum;
import com.cksys.achievement.service.IUserService;
import com.cksys.achievement.service.impl.CustomUserDetailsServiceImpl;
import com.cksys.achievement.utils.CacheUtils;
import com.cksys.achievement.utils.EmailUtil;
import com.cksys.achievement.utils.RestResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.Email;

/**
 * @ClassName: EmailController
 * @author: zyx
 * @E-mail: 1377631190@qq.com
 * @DATE: 2020/4/19 12:24
 */
@Controller
@RequestMapping("/email")
public class EmailController {

    @Autowired
    IUserService userService;

    @Autowired
    CacheUtils cacheUtils;

    @Autowired
    CustomUserDetailsServiceImpl customUserDetailsService;

    @Autowired
    EmailUtil emailUtil;

    public static String EMAIL_ACTIVATION;

    @Value("${email.activation}")
    public void setEmailActivation(String emailActivation) {
        EMAIL_ACTIVATION = emailActivation;
    }

    @GetMapping("/activation")
    public String activation(@RequestParam("email") String email,
                             HttpServletRequest request,
                             @RequestParam("flag") String flag) {
        String emailFlag = (String) cacheUtils.get("emailFlag");
        String username = (String) cacheUtils.get("username");
        if (null == emailFlag || "".equals(emailFlag) || !emailFlag.equals(flag)) {
            request.setAttribute("flag", false);
            return "utils/emailActivation";
        }
        boolean update = userService.update(new User().setEmailFlag(EmailStatusEnum.IS_ACTIVATION),
                new LambdaQueryWrapper<User>().eq(User::getUsername, username).eq(User::getEmail, email));
        if (update) {
            UserDetails userDetails1 = customUserDetailsService.loadUserByUsername(username);
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userDetails1, authentication.getCredentials(), authentication.getAuthorities());
            auth.setDetails(authentication.getDetails());
            SecurityContextHolder.getContext().setAuthentication(auth);
            request.setAttribute("flag", true);
        } else {
            request.setAttribute("flag", false);
        }
        return "utils/emailActivation";
    }

    /**
     *
     * @param userDetails
     * @param email
     * @return
     */
    @PostMapping("/change")
    @ResponseBody
    public RestResponse changeEmail(@AuthenticationPrincipal UserDetails userDetails,
                                    @Valid @Email(message = "请输入邮箱！") @RequestParam("email") String email) {
        if (userService.count(new LambdaQueryWrapper<User>().eq(User::getEmail, email)
                .eq(User::getEmailFlag, EmailStatusEnum.IS_ACTIVATION)) > 0) {
            return RestResponse.fail("邮箱已被占用");
        }
        String url = EMAIL_ACTIVATION;
        User byUserName = userService.getByUserName(userDetails.getUsername());
        if (byUserName == null) {
            return RestResponse.fail("修改失败！");
        }
        Integer flag = generateCode();
        cacheUtils.put("emailFlag", String.valueOf(flag), 5);
        cacheUtils.put("username", byUserName.getUsername(), 5);
        url = String.format(url, email, flag);
        String content = emailUtil.emailCodeTemplate.replace("${name}", byUserName.getUsername()).replace("${link}", url).replace("${link}", url);
        boolean b = emailUtil.sendHTMLEmail("邮箱绑定", content, email);
        if (b) {
            byUserName.setEmailFlag(EmailStatusEnum.NO_ACTIVATION).setEmail(email);
            userService.updateById(byUserName);
            return RestResponse.ok("修改成功！请前往邮箱激活！");
        } else {
            return RestResponse.fail("修改失败！");
        }
    }

    @GetMapping("/get")
    @ResponseBody
    public RestResponse getEmail(@RequestParam String username) {
        User byUserName = userService.getByUserName(username);
        if (null == byUserName) {
            return RestResponse.fail("请检查用户名！");
        }
        @Email(message = "邮箱格式错误！") String email = byUserName.getEmail();
        if (null == email) {
            return RestResponse.fail("邮箱为空！");
        }
        String code = String.valueOf(generateCode());
        String content = emailUtil.findPassowrdCodeTemplate.replace("${name}", byUserName.getUsername()).replace("${code}", code);
        Boolean aBoolean = emailUtil.sendHTMLEmail("找回密码", content, email);
        if (aBoolean) {
            cacheUtils.put("findPasswordCode", code, 5);
            return RestResponse.ok();
        } else {
            return RestResponse.fail();
        }
    }

    private Integer generateCode() {
        return (int)(Math.random() * 8998) + 1000 + 1;
    }

}
